#include "FltFile.hpp"
#include "Mesh.hpp"

#include <fstream>
using namespace std;

namespace
{
   double ReadDouble(const char*& c)
   {
      char number[100];
      int i = 0;
      while (*c != ',' && *c != '}')
      {
         number[i++] = *c++;
      }
      number[i] = 0;
      return atof(number);
   }

   int ReadInt(const char*& c)
   {
      char number[100];
      int i = 0;
      while (*c != ',' && *c != '}')
      {
         number[i++] = *c++;
      }
      number[i] = 0;
      return atoi(number);
   }
   void MakeTri(std::vector<Face>& faces, int a, int b, int c, int m1, int m2)
   {
      Face f;
      f.materials[0] = m1;
      f.materials[1] = m2;
      f.vertex[0] = a-1;
      f.vertex[1] = b-1;
      f.vertex[2] = c-1;
      faces.push_back(f);
   }

   int ReadTri(const char*& c, std::vector<Face>& faces)
   {
      int triCount = 0;
      if (*c == '{')
      {
         int vals[20];
         int valCount=0;
         for (; valCount < 20; ++valCount)
         {
            ++c;
            vals[valCount] = ReadInt(c); 
            if (*c == '}') break;
         }
         ++valCount;
         ++c;
         if (valCount == 3 + 2 + 2)
         {
            MakeTri(faces, vals[0], vals[1], vals[2], vals[3], vals[4]);
            triCount = 1;
         }
         else if (valCount == 4 + 2 + 2)
         {
            MakeTri(faces, vals[0], vals[1], vals[2], vals[4], vals[5]);
            MakeTri(faces, vals[0], vals[2], vals[3], vals[4], vals[5]);
            triCount = 2;
         }
      }
      return triCount;
   }
   bool ReadTriOld(const char*& c, Face& t)
   {
      bool ok = false;
      if (*c == '{')
      {
         ++c;
         t.vertex[0] = ReadInt(c)-1; ++c;
         t.vertex[1] = ReadInt(c)-1; ++c;
         t.vertex[2] = ReadInt(c)-1; ++c;
         int ints[8];
         int intCount = 0;
         for (int i = 0; i < 8; ++i)
         {
            ints[i] = ReadInt(c); 
            ++intCount;
            if (*c == '}') break;
            ++c;
         }
         ++c;
         t.materials[0] = t.materials[1] = -999;
         if (intCount != 4)
         {
            return false;
            intCount = intCount;
         }
         for (int i = 0; i < intCount - 2; ++i)
         {
            t.materials[i] = ints[i];
         }
         if (t.vertex[1] < 0 || t.vertex[2] < 0) return false;
         ok = true;
      }
      else
      {
         ok = false;
      }
      return ok;
   }

   bool ReadVert(const char*& c, Vec3& v)
   {
      bool ok = false;
      if (*c == '{')
      {
         ++c;
         v[0] = (float)ReadDouble(c); ++c;
         v[1] = (float)ReadDouble(c); ++c;
         v[2] = (float)ReadDouble(c); 
         ++c;
         ok = true;
      }
      else
      {
         ok = false;
      }
      return ok;
   }
}

void FltFile::Read(const std::string& aFileName,
                   Mesh&              aMesh)
{
   ifstream file(aFileName.c_str());
   file.seekg(0, ios_base::end);
   int fileSize = file.tellg();
   file.seekg(0);
   char* fileData = new char[fileSize];
   file.read(fileData, fileSize);

   const char* input = fileData + 2;
   
   while (1)
   {
      ReadTri(input, *aMesh.faces);
      if (*input!=',')
      {
         break;
      }
      ++input;
   }
   input+=3;
   aMesh.verts.push_back(Vec3());
   while (ReadVert(input, aMesh.verts.back()))
   {
      aMesh.verts.push_back(Vec3());
      if (*input!=',')
      {
         break;
      }
      ++input;
   }
}
